This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

##all viruses - target and off target

library(tidyverse)
── Attaching core tidyverse packages ──────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.2     ── Conflicts ────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(ggpubr)
library(tidyplots)

Attaching package: ‘tidyplots’

The following object is masked from ‘package:ggpubr’:

    gene_expression
library(ggthemes)
library(scales)

Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor

Figure 1 - linear model

Read-in data

#Linear model for TE data - separated by virus
#November 2024

#viral read depth
#use bowtie2 data

library(tidyverse)
library(broom)
library(boot)

####read counts/normalised read counts####

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

####read depths####

#import and combine read depth files

depth_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

Format data


depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- left_join(depths_bt_all, metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  ,
  .default = "RNA"
  ))

####linear model for spike in viruses - mean read depth####

depths_reads_sub <- depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  mutate(log_depth = log10(mean_depth)) |>
  mutate(log_viral_load = log10(Viral.load))

#inspect data
hist(depths_reads_sub$mean_depth)
hist(depths_reads_sub$Viral.load)
hist(depths_reads_sub$log_depth)
hist(depths_reads_sub$log_viral_load)

summary(depths_reads_sub$log_depth)
summary(depths_reads_sub$log_viral_load)

model

#all viruses together

lm1 <-
  glm(log_depth ~ log_viral_load * virus,
      data = depths_reads_sub,
      family = "gaussian")

summary(lm1)

glm.diag.plots(lm1)

pred <- predict(lm1, type = "response")

rsq <- function (x, y) {
  cor(x, y) ^ 2
}

rsq(depths_reads_sub$log_depth, pred)

##split by viruses

cols <- c("#4477AA",
          "#66CCEE",
          "#228833",
          "#CCBB44",
          "#EE6677",
          "#AA3377")

facet_names <- c(
  "Human_adenovirus_40" = "Human adenovirus 40",
  "Human_betaherpesvirus" = "Human betaherpesvirus",
  "Human_respiratory_syncytial_virus" = "Human respiratory syncytial virus",
  "Influenza_B_virus" = "Influenza B virus",
  "Mammalian_orthoreovirus3" = "Mammalian orthoreovirus 3",
  "Zika_virus" = "Zika virus"
)

virus <- (unique(depths_reads_sub$virus)) %>%
  rep(., each = 2) %>%
  data.frame()

list_models <- 
  depths_reads_sub |>
  group_split(virus) |>
  map( ~ lm(log_depth ~ log_viral_load, data = .))

lm_tidy <- 
  map(list_models, broom::tidy) %>%
  do.call(rbind.data.frame, .) %>%
  cbind(virus, .) %>%
  rename(virus = ".") %>%
  select(virus, term, estimate) %>%
  pivot_wider(names_from = "term", values_from = "estimate")

lm_summary <- depths_reads_sub |>
  group_by(virus) |>
  summarise(
    Intercept = lm(log_depth ~ log_viral_load)$coefficients[1],
    Coeff_x1 = lm(log_depth ~ log_viral_load)$coefficients[2],
    R2 = summary(lm(log_depth ~ log_viral_load))$r.squared,
    pvalue = summary(lm(log_depth ~ log_viral_load))$coefficients["log_viral_load", 4]
  )

lm_combined <- 
  left_join(lm_tidy, lm_summary, by = "virus")

Make plot

Final plot

#ggsave("figures/compare_spike_ins_atcc/model_readdepth_dedup.png")

ggsave("figures/manuscript_figure_2025/PDF/Figure_1.pdf",
       width = 8,
       height = 5)

ggsave("figures/manuscript_figure_2025/PNG/Figure_1.png",
       width = 8,
       height = 5)

——————–

>>>> now redundant? - Figure 1: plots of TE experiment data - read counts and read depths

Read-in data

#ATCC genomes updated version
#October 2024

#viral load vs read count normalised using different methods, comparing deduplicated and non-deduplicated
#use bowtie2 data

####read counts/normalised read counts####

#metadata

metadata <- read.csv("metadata/sampleIDs_TESpikeIn.csv", header = TRUE)

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

Format data

#change labels in facet plots

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

cols <- c("#4477AA",
          "#66CCEE",
          "#228833",
          "#CCBB44",
          "#EE6677",
          "#AA3377")

Make plots


#plot viral read counts (non normalised)

read_count <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(matched),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  ylab("log10(Viral Reads)") +
  xlab("Log (Viral load)") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))

#ggsave("figures/compare_spike_ins_atcc/read_counts.pdf",width=8,height=6)

#normalise by raw read count

read_count_norm1 <- counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts1),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  ylab("log10(viral reads/cleaned reads)") +
  xlab("Log (Viral load)") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))

#normalise by raw read count and genome length

read_count_norm2 <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = (Viral.load),
    y = log10(norm_counts2),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  ylab("Log (viral reads/cleaned reads/genome length)") +
  xlab("Log (Viral load)") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))

plot just the two lefthand panels from the original figure

plot viral read counts (non normalised)


##deduplicated only

read_count_dedup <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(matched),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE, method = "lm") +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  ylab("Log (Viral Reads)") +
  xlab("Log (Viral load)") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))

#normalise by raw read count and genome length

read_count_norm2_dedup <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts2),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE, method = "lm") +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  ylab("Log (viral reads/cleaned reads/genome length)") +
  xlab("Log (Viral load)") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))

Final plot

——————–

Figure S1

Read depths

####read depths####

#import and combine read depth files

depth_dedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv"
  )

depth_nodedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )

depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- 
  depths_bt_all |>
  left_join(metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  )) |>
  rename(Viral.load = `Viral load`)

Make plots


read_depths <- 
  depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(mean_depth),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  ylab("Log (mean read depth)") +
  xlab("Log (Viral load)") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))

#ggsave("figures/compare_spike_ins_atcc/mean_depth.pdf",width=8,height=6)

Final plot

——————–

Figure S2

Read-in data / Make plots

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

####compare library capture pool####

cols3 <- c("#228833", "#AA3377")

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

metadata3 <- 
  metadata |>
  select(Sample.ID, Pool.for.sequencing) |>
  rename(Sample_id = Sample.ID) |>
  rename(Pool = Pool.for.sequencing)

counts_pool <- left_join(counts_reads_norm, metadata3, by = "Sample_id")

Make plots


pool_counts_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (Viral Reads)") + xlab("Log (Viral load)") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
  scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))
  

# pool_readcounts_norm <- 
#   counts_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(norm_counts1))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     # axis.text.x = element_blank(),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("log10(viral reads/cleaned reads)")

pool_norm1_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray") 
  ) +
  ylab("log10(viral reads/cleaned reads)") + xlab("Log (Viral load)") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
    scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))

# pool_readcounts_norm2 <- 
#   counts_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(norm_counts2))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     # axis.text.x = element_blank(),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("log10(viral reads/cleaned reads/genome length)")


pool_norm2_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("log10(viral reads/cleaned reads/genome length)") + xlab("Log (Viral load)") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
    scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))


#import and combine read depth files

depth_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- 
  left_join(depths_bt_all, metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

depths_pool <- left_join(depths_reads, metadata3, by = "Sample_id")

# pool_readdepths <- 
#   depths_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(mean_depth))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     axis.text.x = element_text(angle = 45, hjust = 1),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("Log (mean read depth)")

pool_depths_sum <-
  depths_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(mean_depth),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (mean read depth)") +
  xlab("Log (Viral load)") + 
  scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5}))) +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2"))

Final plot

ggarrange(
  pool_counts_sum,
  pool_norm1_sum,
  pool_norm2_sum,
  pool_depths_sum,
  nrow = 2,
  ncol = 2,
  common.legend = TRUE, 
  align = "hv"
)
Error: object 'pool_counts_sum' not found

——————–

Figure S3


##plots of read counts and viral read counts
#November 2024

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import read count files

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

#import viral reads mapped (to calculate proportions)

viral_reads_dedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_dedup_atcc_ref_20241108.csv",
    header = TRUE
  )

viral_reads_nodedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_nodedup_atcc_ref_20241108.csv",
    header = TRUE
  )

cols2 <- c("#BB5566", "#004488")

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

reads_metadata_dedup <-
  left_join(counts_dedup_bt, metadata2, by = "Sample_id")

reads_viral_dedup <-
  left_join(reads_metadata_dedup, viral_reads_dedup, by = "Sample_id")

reads_metadata_nodedup <-
  left_join(counts_nodedup_bt, metadata2, by = "Sample_id")

reads_viral_nodedup <-
  left_join(reads_metadata_nodedup, viral_reads_nodedup, by = "Sample_id")

reads_viral_all <- rbind(reads_viral_dedup, reads_viral_nodedup)


reads_plot <- 
  reads_viral_all |>
  group_by(Background, Sample_id, Viral.load, type) |>
  summarise(
    total_reads = (QC_reads * 2),
    viral_reads = total_virus_reads,
    ATCC_reads = sum(matched),
    prop_ATCC = ATCC_reads / total_reads,
    prop_viral = total_virus_reads / total_reads,
    diff = viral_reads - ATCC_reads
  ) |>
  unique()
Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in dplyr 1.1.0.
Please use `reframe()` instead.
When switching from `summarise()` to `reframe()`, remember that `reframe()` always returns an ungrouped data frame and adjust accordingly.`summarise()` has grouped output by 'Background', 'Sample_id', 'Viral.load', 'type'. You can override using the `.groups` argument.

Make plots

Final plot

——————–

No longer required? Figure S4

Make plots

####read counts/depths split by background####

#change labels in facet plots

facet_names_bg <- c(
  "dedup_TE" = "Deduplicated",
  "nodedup_TE" = "Non-Deduplicated",
  "p2" = "P1",
  "p8" = "P2"
)

#break down by Background x virus

background_counts_reads <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(matched),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels =
      c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
      )
  ) +
  scale_x_log10(labels = scales::label_log10()) +
  ylab("log10(Viral Reads)")

backgrounds_counts_reads_norm <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts1),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_bw() +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(label = scales::label_log10()) +
  ylab("log10(viral reads/cleaned reads)")

backgrounds_counts_reads_norm2 <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts2),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(labels = scales::label_log10()) +
  ylab("log10(viral reads/cleaned reads/genome length)")

background_read_depths <- 
  depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(mean_depth),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray"),
    axis.title.y = element_text(size = 10),
    legend.title = element_blank()
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(label = scales::label_log10()) +
  ylab("log10(mean read depth)")

Final plot

——————–

——————–

>>> Figure 2: plots of TE experiment data - genome coverage & per site coverage

Read-in data


#plots of TE experiment data - genome coverage & per site coverage
#also separated by viruses
#ATCC genomes updated version
#October 2024

#use bowtie2 data

####genome coverage####

unzip(zipfile = "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv.zip", exdir = "data_TE/")

unzip(zipfile = "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv.zip", exdir = "data_TE/")

dedup_per_site <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv"
  )


nodedup_per_site <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )

file.remove("data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv")

file.remove( "data_TE/TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv")

#add length column from read depth file to per site file

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- 
  metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files

#deduplicated and non-deduplicated

counts_dedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv"
  )

counts_nodedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

Format data

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- 
  counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

lengths <- 
  counts_reads_norm |>
  select(virus, length) |>
  distinct()

#calculate genome coverage

persite_coverage_dedup <- 
  dedup_per_site |>
  rename(Viral.load = `Viral load`) |>
  group_by(Sample_id, virus, Viral.load, Background, type) |>
  filter(coverage > 0) |>
  summarise(genome_coverage = n()) |>
  left_join(lengths) |>
  mutate(percent_coverage = genome_coverage / length)

persite_coverage_nodedup <- 
  nodedup_per_site |>
  rename(Viral.load = `Viral load`) |>
  group_by(Sample_id, virus, Viral.load, Background, type) |>
  filter(coverage > 0) |>
  summarise(genome_coverage = n()) |>
  left_join(lengths) |>
  mutate(percent_coverage = genome_coverage / length)

persite_coverage_both <-
  rbind(persite_coverage_dedup, 
        persite_coverage_nodedup)

coverage_labels <- c("0" = "Control",
                     "100" = "10^{2}",
                     "1000" = "10^{3}",
                     "10000" = "10^{5}",
                     "dedup_TE" = "Deduplicated",
                     "nodedup_TE"= "Non-Deduplicated")

coverage_labels2 <- c("0" = "Control",
                      "100" = "10^{2}",
                      "1000" = "10^{3}",
                      "10000" = "10^{5}")

Make plots

Final plot

——————–

——————–

Figure S4

Final plot

ggsave("figures/manuscript_figure_2025/PDF/Figure_S4.pdf",
       width=15,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S4.png",
       width=15,
       height=10)

——————–

Figure S5

####Final plot

file.remove("figures/manuscript_figure_2025/PDF/FigureS6.pdf")
[1] TRUE

——————–

Figure S6

####Final plot

file.remove("figures/manuscript_figure_2025/PNG/Figure_S6.pdf")
[1] TRUE

——————–

Figure S7

HBV <- 
persite_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  filter(virus == "Human_betaherpesvirus") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(x = site, y = coverage, fill = Background)) +
  geom_col() +
  facet_wrap(Viral.load ~ Sample_id, label = label_parsed) +
  ylab("Coverage") +
  ggtitle("Human Betaherpesvirus (deduplicated)") +
  guides(fill = guide_legend(title = "Background")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols2, labels = c("P1", "P2"))

####Final plot

file.remove("figures/manuscript_figure_2025/PNG/Figure_S7.pdf")
[1] TRUE

——————–

Figure S8

#have to do these differently due to segmentation


FLU_ME1 <- persite_norm |>
  filter(virus == "Influenza_B_virus") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p2") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Coverage") +
  ggtitle("Influenza B virus (Background 1 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols4, label = c(expression("10"^"2"), expression("10"^"3"), expression("10"^"5")))

FLU_ME2 <- persite_norm |>
  filter(virus == "Influenza_B_virus") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p2") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Coverage") +
  ggtitle("Influenza B virus (Background 2 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols4, label = c(expression("10"^"2"), expression("10"^"3"), expression("10"^"5")))


ggarrange(FLU_ME1, FLU_ME2, ncol = 2, common.legend = TRUE)

####Final plot


ggsave("figures/manuscript_figure_2025/PDF/Figure_S8.pdf",
       width=20,
       height=12,
       dpi=600)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S8.png",
       width=20,
       height=12)

——————–

Figure S9


REO_ME1 <- 
  persite_norm |>
  filter(virus == "Mammalian_orthoreovirus3") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p2") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("log10(Coverage)") +
  ggtitle("Mammalian orthoreovirus 3 (Background 1 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top",
    panel.grid.major = element_line(linewidth = 0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth = 0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols4,
                    label = c(
                      expression("10" ^ "2"),
                      expression("10" ^ "3"),
                      expression("10" ^ "5")
                    ))

REO_ME2 <- 
  persite_norm |>
  filter(virus == "Mammalian_orthoreovirus3") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p8") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("log10(Coverage)") +
  ggtitle("Mammalian orthoreovirus 3 (Background 2 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top",
    panel.grid.major = element_line(linewidth = 0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth = 0.1, color = "lightgray")
  ) + scale_y_log10() +
  scale_fill_manual(values = cols4,
                    label = c(
                      expression("10" ^ "2"),
                      expression("10" ^ "3"),
                      expression("10" ^ "5")
                    ))

ggarrange(REO_ME1, REO_ME2, ncol = 2, common.legend = TRUE)

####Final plot

ggsave("figures/manuscript_figure_2025/PDF/Figure_S9.pdf",
       width=20,
       height=12,
       dpi=600)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S9.png",
       width=20,
       height=12,
       dpi=600)

——————–

>>>> Figure 3: all viruses - target and off target

Read-in data

metadata2 <-
  metadata |>
  select(
    Sample.ID,
    Background.sample,
    Viral.load,
    Number.of.read.pairs..quality.adaptor.trimmed.
  ) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)
Error in rename(rename(select(metadata, Sample.ID, Background.sample,  : 
  could not find function "rename"

Format data

Make plots

Dedup – viral reads, prop all reads, and prop viral reads

Final plot

—-nodedup results —-

——————–

LS0tCnRpdGxlOiAidGFyZ2V0X29mZnRhcmdldCIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpgYGB7cn0KIyNhbGwgdmlydXNlcyAtIHRhcmdldCBhbmQgb2ZmIHRhcmdldAoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KHRpZHlwbG90cykKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShzY2FsZXMpCgpgYGAKCiMjIyBGaWd1cmUgMSAtIGxpbmVhciBtb2RlbAoKIyMjIyBSZWFkLWluIGRhdGEKYGBge3J9CiNMaW5lYXIgbW9kZWwgZm9yIFRFIGRhdGEgLSBzZXBhcmF0ZWQgYnkgdmlydXMKI05vdmVtYmVyIDIwMjQKCiN2aXJhbCByZWFkIGRlcHRoCiN1c2UgYm93dGllMiBkYXRhCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShicm9vbSkKbGlicmFyeShib290KQoKIyMjI3JlYWQgY291bnRzL25vcm1hbGlzZWQgcmVhZCBjb3VudHMjIyMjCgojbWV0YWRhdGEKCm1ldGFkYXRhIDwtCiAgcmVhZC5jc3YoCiAgICAibWV0YWRhdGEvc2FtcGxlSURzX1RFU3Bpa2VJbi5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCm1ldGFkYXRhMiA8LSBtZXRhZGF0YSB8PgogIHNlbGVjdChTYW1wbGUuSUQsIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGNvdW50IGZpbGVzCiNkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX25vZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX2J0X2FsbCA8LSByYmluZChjb3VudHNfZGVkdXBfYnQsIGNvdW50c19ub2RlZHVwX2J0KQoKY291bnRzX3JlYWRzIDwtIGxlZnRfam9pbihjb3VudHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgojIyMjcmVhZCBkZXB0aHMjIyMjCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgZGVwdGggZmlsZXMKCmRlcHRoX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aF9ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmBgYAoKIyMjIyBGb3JtYXQgZGF0YQpgYGB7cn0KCmRlcHRoc19idF9hbGwgPC0gcmJpbmQoZGVwdGhfZGVkdXBfYnQsIGRlcHRoX25vZGVkdXBfYnQpCgpkZXB0aHNfcmVhZHMgPC0gbGVmdF9qb2luKGRlcHRoc19idF9hbGwsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgojIyMjbGluZWFyIG1vZGVsIGZvciBzcGlrZSBpbiB2aXJ1c2VzIC0gbWVhbiByZWFkIGRlcHRoIyMjIwoKZGVwdGhzX3JlYWRzX3N1YiA8LSBkZXB0aHNfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIG11dGF0ZShsb2dfZGVwdGggPSBsb2cxMChtZWFuX2RlcHRoKSkgfD4KICBtdXRhdGUobG9nX3ZpcmFsX2xvYWQgPSBsb2cxMChWaXJhbC5sb2FkKSkKCiNpbnNwZWN0IGRhdGEKaGlzdChkZXB0aHNfcmVhZHNfc3ViJG1lYW5fZGVwdGgpCmhpc3QoZGVwdGhzX3JlYWRzX3N1YiRWaXJhbC5sb2FkKQpoaXN0KGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoKQpoaXN0KGRlcHRoc19yZWFkc19zdWIkbG9nX3ZpcmFsX2xvYWQpCgpzdW1tYXJ5KGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoKQpzdW1tYXJ5KGRlcHRoc19yZWFkc19zdWIkbG9nX3ZpcmFsX2xvYWQpCgpgYGAKCiMjIyMgbW9kZWwKYGBge3J9CiNhbGwgdmlydXNlcyB0b2dldGhlcgoKbG0xIDwtCiAgZ2xtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkICogdmlydXMsCiAgICAgIGRhdGEgPSBkZXB0aHNfcmVhZHNfc3ViLAogICAgICBmYW1pbHkgPSAiZ2F1c3NpYW4iKQoKc3VtbWFyeShsbTEpCgpnbG0uZGlhZy5wbG90cyhsbTEpCgpwcmVkIDwtIHByZWRpY3QobG0xLCB0eXBlID0gInJlc3BvbnNlIikKCnJzcSA8LSBmdW5jdGlvbiAoeCwgeSkgewogIGNvcih4LCB5KSBeIDIKfQoKcnNxKGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoLCBwcmVkKQoKIyNzcGxpdCBieSB2aXJ1c2VzCgpjb2xzIDwtIGMoIiM0NDc3QUEiLAogICAgICAgICAgIiM2NkNDRUUiLAogICAgICAgICAgIiMyMjg4MzMiLAogICAgICAgICAgIiNDQ0JCNDQiLAogICAgICAgICAgIiNFRTY2NzciLAogICAgICAgICAgIiNBQTMzNzciKQoKZmFjZXRfbmFtZXMgPC0gYygKICAiSHVtYW5fYWRlbm92aXJ1c180MCIgPSAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIgPSAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAiSHVtYW5fcmVzcGlyYXRvcnlfc3luY3l0aWFsX3ZpcnVzIiA9ICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICJJbmZsdWVuemFfQl92aXJ1cyIgPSAiSW5mbHVlbnphIEIgdmlydXMiLAogICJNYW1tYWxpYW5fb3J0aG9yZW92aXJ1czMiID0gIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICJaaWthX3ZpcnVzIiA9ICJaaWthIHZpcnVzIgopCgp2aXJ1cyA8LSAodW5pcXVlKGRlcHRoc19yZWFkc19zdWIkdmlydXMpKSAlPiUKICByZXAoLiwgZWFjaCA9IDIpICU+JQogIGRhdGEuZnJhbWUoKQoKbGlzdF9tb2RlbHMgPC0gCiAgZGVwdGhzX3JlYWRzX3N1YiB8PgogIGdyb3VwX3NwbGl0KHZpcnVzKSB8PgogIG1hcCggfiBsbShsb2dfZGVwdGggfiBsb2dfdmlyYWxfbG9hZCwgZGF0YSA9IC4pKQoKbG1fdGlkeSA8LSAKICBtYXAobGlzdF9tb2RlbHMsIGJyb29tOjp0aWR5KSAlPiUKICBkby5jYWxsKHJiaW5kLmRhdGEuZnJhbWUsIC4pICU+JQogIGNiaW5kKHZpcnVzLCAuKSAlPiUKICByZW5hbWUodmlydXMgPSAiLiIpICU+JQogIHNlbGVjdCh2aXJ1cywgdGVybSwgZXN0aW1hdGUpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAidGVybSIsIHZhbHVlc19mcm9tID0gImVzdGltYXRlIikKCmxtX3N1bW1hcnkgPC0gZGVwdGhzX3JlYWRzX3N1YiB8PgogIGdyb3VwX2J5KHZpcnVzKSB8PgogIHN1bW1hcmlzZSgKICAgIEludGVyY2VwdCA9IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSRjb2VmZmljaWVudHNbMV0sCiAgICBDb2VmZl94MSA9IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSRjb2VmZmljaWVudHNbMl0sCiAgICBSMiA9IHN1bW1hcnkobG0obG9nX2RlcHRoIH4gbG9nX3ZpcmFsX2xvYWQpKSRyLnNxdWFyZWQsCiAgICBwdmFsdWUgPSBzdW1tYXJ5KGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSkkY29lZmZpY2llbnRzWyJsb2dfdmlyYWxfbG9hZCIsIDRdCiAgKQoKbG1fY29tYmluZWQgPC0gCiAgbGVmdF9qb2luKGxtX3RpZHksIGxtX3N1bW1hcnksIGJ5ID0gInZpcnVzIikKCgpgYGAKCiMjIyMgTWFrZSBwbG90CmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQpnZ3Bsb3QoKSArCiAgZ2VvbV9wb2ludChkYXRhID0gZGVwdGhzX3JlYWRzX3N1YiwKICAgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoVmlyYWwubG9hZCwgbWVhbl9kZXB0aCwgY29sb3IgPSB2aXJ1cykpICsKICBnZW9tX2FibGluZShkYXRhID0gbG1fY29tYmluZWQsIGFlcyhpbnRlcmNlcHQgPSBgKEludGVyY2VwdClgLCBzbG9wZSA9IGxvZ192aXJhbF9sb2FkKSwgbGluZXR5cGU9ImRvdHRlZCIpICsKICBnZW9tX3RleHQoZGF0YSA9IGxtX2NvbWJpbmVkLAogICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLAogICAgICAgICAgICBhZXMoCiAgICAgICAgICAgICAgeCA9IDYqMTAwMDAsCiAgICAgICAgICAgICAgeSA9IDIsCiAgICAgICAgICAgICAgbGFiZWwgPSByb3VuZChDb2VmZl94MSwgZGlnaXRzID0gMikpLAogICAgICAgICAgICBzaXplID0gMy41KSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBsbV9jb21iaW5lZCwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwKICAgICAgICAgICAgYWVzKHggPSAxLjUqMTAwMDAsIAogICAgICAgICAgICAgICAgeSA9IDIsIAogICAgICAgICAgICAgICAgbGFiZWwgPSAiU2xvcGUgPSIpLAogICAgICAgICAgICBzaXplID0gMy41KSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBsbV9jb21iaW5lZCwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwKICAgICAgICAgICAgYWVzKAogICAgICAgICAgICAgIHggPSA2KjEwMDAwLAogICAgICAgICAgICAgIHkgPSA2LAogICAgICAgICAgICAgIGxhYmVsID0gcm91bmQoUjIsIGRpZ2l0cyA9IDIpKSwKICAgICAgICAgICAgc2l6ZSA9IDMuNSkgKwogIGdlb21fdGV4dChkYXRhID0gbG1fY29tYmluZWQsCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsCiAgICAgICAgICAgIGFlcyh4ID0gMioxMDAwMCwgCiAgICAgICAgICAgICAgICB5ID0gNiwgCiAgICAgICAgICAgICAgICBsYWJlbCA9ICJSMiA9IiksCiAgICAgICAgICAgIHNpemUgPSAzLjUpICsKICBmYWNldF93cmFwKCB+IHZpcnVzLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IiksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKQogICkgKwogICAgeGxhYigiTG9nIChWaXJhbCBsb2FkKSIpICsgCiAgeWxhYigiTG9nIChNZWFuIFJlYWQgRGVwdGgpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgZ3VpZGVzKGNvbG9yID0gRkFMU0UpICsKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyAKICAgIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKQoKYGBgCgojIyMjIEZpbmFsIHBsb3QKYGBge3J9CiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9tb2RlbF9yZWFkZGVwdGhfZGVkdXAucG5nIikKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfMS5wZGYiLAogICAgICAgd2lkdGggPSA4LAogICAgICAgaGVpZ2h0ID0gNSkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfMS5wbmciLAogICAgICAgd2lkdGggPSA4LAogICAgICAgaGVpZ2h0ID0gNSkKCmBgYAoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyA+Pj4+IG5vdyByZWR1bmRhbnQ/IC0gRmlndXJlIDE6IHBsb3RzIG9mIFRFIGV4cGVyaW1lbnQgZGF0YSAtIHJlYWQgY291bnRzIGFuZCByZWFkIGRlcHRocyAKCiMjIyBSZWFkLWluIGRhdGEKYGBge3J9CiNBVENDIGdlbm9tZXMgdXBkYXRlZCB2ZXJzaW9uCiNPY3RvYmVyIDIwMjQKCiN2aXJhbCBsb2FkIHZzIHJlYWQgY291bnQgbm9ybWFsaXNlZCB1c2luZyBkaWZmZXJlbnQgbWV0aG9kcywgY29tcGFyaW5nIGRlZHVwbGljYXRlZCBhbmQgbm9uLWRlZHVwbGljYXRlZAojdXNlIGJvd3RpZTIgZGF0YQoKIyMjI3JlYWQgY291bnRzL25vcm1hbGlzZWQgcmVhZCBjb3VudHMjIyMjCgojbWV0YWRhdGEKCm1ldGFkYXRhIDwtIHJlYWQuY3N2KCJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsIGhlYWRlciA9IFRSVUUpCgptZXRhZGF0YTIgPC0gbWV0YWRhdGEgfD4KICBzZWxlY3QoU2FtcGxlLklELCBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKSB8PgogIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKCiNpbXBvcnQgYW5kIGNvbWJpbmUgcmVhZCBjb3VudCBmaWxlcwojZGVkdXBsaWNhdGVkIGFuZCBub24tZGVkdXBsaWNhdGVkCgpjb3VudHNfZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19idF9hbGwgPC0gcmJpbmQoY291bnRzX2RlZHVwX2J0LCBjb3VudHNfbm9kZWR1cF9idCkKCmNvdW50c19yZWFkcyA8LSBsZWZ0X2pvaW4oY291bnRzX2J0X2FsbCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKI25vcm1hbGlzZSBieSBib3RoIHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoIC0gc2hvdWxkIGJlIHRoZSBzYW1lIGFzIG1lYW4gcmVhZCBkZXB0aAoKY291bnRzX3JlYWRzX25vcm0gPC0gY291bnRzX3JlYWRzIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMSA9IG1hdGNoZWQgLyBRQ19yZWFkcykgfD4KICBtdXRhdGUobm9ybV9jb3VudHMyID0gbWF0Y2hlZCAvIFFDX3JlYWRzIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShub3JtX2NvdW50czMgPSBtYXRjaGVkIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShnZW5vbWVfc3RydWN0dXJlID0gY2FzZV93aGVuKCgKICAgIHZpcnVzID09ICJIdW1hbl9hZGVub3ZpcnVzXzQwIiB8CiAgICAgIHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiCiAgKSB+ICJETkEiLAogIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKYGBgCgoKIyMjIEZvcm1hdCBkYXRhCmBgYHtyfQojY2hhbmdlIGxhYmVscyBpbiBmYWNldCBwbG90cwoKZmFjZXRfbmFtZXMgPC0gYygiZGVkdXBfVEUiID0gIkRlZHVwbGljYXRlZCIsCiAgICAgICAgICAgICAgICAgIm5vZGVkdXBfVEUiID0gIk5vbi1EZWR1cGxpY2F0ZWQiKQoKY29scyA8LSBjKCIjNDQ3N0FBIiwKICAgICAgICAgICIjNjZDQ0VFIiwKICAgICAgICAgICIjMjI4ODMzIiwKICAgICAgICAgICIjQ0NCQjQ0IiwKICAgICAgICAgICIjRUU2Njc3IiwKICAgICAgICAgICIjQUEzMzc3IikKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7cn0KCiNwbG90IHZpcmFsIHJlYWQgY291bnRzIChub24gbm9ybWFsaXNlZCkKCnJlYWRfY291bnQgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nMTAobWF0Y2hlZCksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICB5bGFiKCJsb2cxMChWaXJhbCBSZWFkcykiKSArCiAgeGxhYigiTG9nIChWaXJhbCBsb2FkKSIpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvcmVhZF9jb3VudHMucGRmIix3aWR0aD04LGhlaWdodD02KQoKI25vcm1hbGlzZSBieSByYXcgcmVhZCBjb3VudAoKcmVhZF9jb3VudF9ub3JtMSA8LSBjb3VudHNfcmVhZHNfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2cxMChub3JtX2NvdW50czEpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgeWxhYigibG9nMTAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcykiKSArCiAgeGxhYigiTG9nIChWaXJhbCBsb2FkKSIpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCgojbm9ybWFsaXNlIGJ5IHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoCgpyZWFkX2NvdW50X25vcm0yIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSAoVmlyYWwubG9hZCksCiAgICB5ID0gbG9nMTAobm9ybV9jb3VudHMyKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHlsYWIoIkxvZyAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcy9nZW5vbWUgbGVuZ3RoKSIpICsKICB4bGFiKCJMb2cgKFZpcmFsIGxvYWQpIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCmBgYAoKIyMjIHBsb3QganVzdCB0aGUgdHdvIGxlZnRoYW5kIHBhbmVscyBmcm9tIHRoZSBvcmlnaW5hbCBmaWd1cmUKYGBge3IsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD04fQoKZ2dhcnJhbmdlKHJlYWRfY291bnQsCiAgICAgICAgICByZWFkX2NvdW50X25vcm0yLAogICAgICAgICAgbnJvdyA9IDIsCiAgICAgICAgICBjb21tb24ubGVnZW5kID0gVFJVRSkKCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9sb2dfcmVhZF9jb3VudF9kZXB0aF8ycGFuZWxzLnBuZyIsd2lkdGg9MTAsaGVpZ2h0PTcpCgoKYGBgCgojIyMgcGxvdCB2aXJhbCByZWFkIGNvdW50cyAobm9uIG5vcm1hbGlzZWQpCmBgYHtyfQoKIyNkZWR1cGxpY2F0ZWQgb25seQoKcmVhZF9jb3VudF9kZWR1cCA8LSAKICBjb3VudHNfcmVhZHNfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG1hdGNoZWQpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSwgbWV0aG9kID0gImxtIikgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICB5bGFiKCJMb2cgKFZpcmFsIFJlYWRzKSIpICsKICB4bGFiKCJMb2cgKFZpcmFsIGxvYWQpIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCiNub3JtYWxpc2UgYnkgcmF3IHJlYWQgY291bnQgYW5kIGdlbm9tZSBsZW5ndGgKCnJlYWRfY291bnRfbm9ybTJfZGVkdXAgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2cxMChub3JtX2NvdW50czIpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSwgbWV0aG9kID0gImxtIikgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICB5bGFiKCJMb2cgKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMvZ2Vub21lIGxlbmd0aCkiKSArCiAgeGxhYigiTG9nIChWaXJhbCBsb2FkKSIpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCmBgYAoKIyMjICoqKkZpbmFsIHBsb3QqKioKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTEwfQojcGxvdCBqdXN0IHRoZSB0d28gbGVmdGhhbmQgcGFuZWxzIGZyb20gdGhlIG9yaWdpbmFsIGZpZ3VyZQoKZ2dhcnJhbmdlKAogIHJlYWRfY291bnRfZGVkdXAsCiAgcmVhZF9jb3VudF9ub3JtMl9kZWR1cCwKICBucm93ID0gMiwKICBjb21tb24ubGVnZW5kID0gVFJVRSwKICBhbGlnbiA9ICJodiIKKQoKIyBnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9sb2dfcmVhZF9jb3VudF9kZXB0aF8ycGFuZWxzX2RlZHVwLnBuZyIsCiMgICAgICAgIHdpZHRoPTEwLAojICAgICAgICBoZWlnaHQ9NykKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzEucGRmIiwKICAgICAgIHdpZHRoPTcsCiAgICAgICBoZWlnaHQ9OCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzEucG5nIiwKICAgICAgIHdpZHRoPTcsCiAgICAgICBoZWlnaHQ9OCkKCmBgYAoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKCiMjIEZpZ3VyZSBTMQoKIyMjIFJlYWQgZGVwdGhzCmBgYHtyfQojIyMjcmVhZCBkZXB0aHMjIyMjCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgZGVwdGggZmlsZXMKCmRlcHRoX2RlZHVwX2J0IDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmRlcHRoX25vZGVkdXBfYnQgPC0KICByZWFkX3RzdigKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIKICApCgpkZXB0aHNfYnRfYWxsIDwtIHJiaW5kKGRlcHRoX2RlZHVwX2J0LCBkZXB0aF9ub2RlZHVwX2J0KQoKZGVwdGhzX3JlYWRzIDwtIAogIGRlcHRoc19idF9hbGwgfD4KICBsZWZ0X2pvaW4obWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKSB8PgogIG11dGF0ZShnZW5vbWVfc3RydWN0dXJlID0gY2FzZV93aGVuKCgKICAgIHZpcnVzID09ICJIdW1hbl9hZGVub3ZpcnVzXzQwIiB8CiAgICAgIHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiCiAgKSB+ICJETkEiLAogIC5kZWZhdWx0ID0gIlJOQSIKICApKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKQoKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7cn0KCnJlYWRfZGVwdGhzIDwtIAogIGRlcHRoc19yZWFkcyB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2cxMChtZWFuX2RlcHRoKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHlsYWIoIkxvZyAobWVhbiByZWFkIGRlcHRoKSIpICsKICB4bGFiKCJMb2cgKFZpcmFsIGxvYWQpIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9tZWFuX2RlcHRoLnBkZiIsd2lkdGg9OCxoZWlnaHQ9NikKCmBgYAoKIyMjICoqKkZpbmFsIHBsb3QqKioKYGBge3IsIHdhcm5pbmcgPSBGQUxTRSwgZWNobyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CgpnZ2FycmFuZ2UoCiAgcmVhZF9jb3VudCwKICByZWFkX2NvdW50X25vcm0xLAogIHJlYWRfY291bnRfbm9ybTIsCiAgcmVhZF9kZXB0aHMsCiAgbnJvdyA9IDIsCiAgbmNvbCA9IDIsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgYWxpZ24gPSAiaHYiCikKCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9sb2dfcmVhZF9jb3VudF9kZXB0aC5wbmciLHdpZHRoPTEwLGhlaWdodD03KQoKI2dnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZXNfcGRmL0ZpZ3VyZVMxLnBkZiIsd2lkdGg9MTAsaGVpZ2h0PTcpCgojYXBwYXJlbnRseSBub3JtYWxpc2VkIHJlYWQgY291bnQgdXNpbmcgbWV0aG9kIDIgc2hvdWxkIG5vdCBhY3R1YWxseSBiZSB0aGUgc2FtZQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TMS5wZGYiLAogICAgICAgd2lkdGggPSAxMiwKICAgICAgIGhlaWdodCA9IDgpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlX1MxLnBuZyIsCiAgICAgICB3aWR0aCA9IDEyLAogICAgICAgaGVpZ2h0ID0gOCkKCgpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIEZpZ3VyZSBTMgoKIyMjIFJlYWQtaW4gZGF0YSAvIE1ha2UgcGxvdHMKYGBge3J9CiNtZXRhZGF0YQoKbWV0YWRhdGEgPC0KICByZWFkLmNzdigKICAgICJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKbWV0YWRhdGEyIDwtIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgY291bnQgZmlsZXMKI2RlZHVwbGljYXRlZCBhbmQgbm9uLWRlZHVwbGljYXRlZAoKY291bnRzX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb3VudHNfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb3VudHNfYnRfYWxsIDwtIHJiaW5kKGNvdW50c19kZWR1cF9idCwgY291bnRzX25vZGVkdXBfYnQpCgpjb3VudHNfcmVhZHMgPC0gbGVmdF9qb2luKGNvdW50c19idF9hbGwsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCiNub3JtYWxpc2UgYnkgYm90aCByYXcgcmVhZCBjb3VudCBhbmQgZ2Vub21lIGxlbmd0aCAtIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBtZWFuIHJlYWQgZGVwdGgKCmNvdW50c19yZWFkc19ub3JtIDwtIGNvdW50c19yZWFkcyB8PgogIG11dGF0ZShub3JtX2NvdW50czEgPSBtYXRjaGVkIC8gUUNfcmVhZHMpIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMiA9IG1hdGNoZWQgLyBRQ19yZWFkcyAvIGxlbmd0aCkgfD4KICBtdXRhdGUobm9ybV9jb3VudHMzID0gbWF0Y2hlZCAvIGxlbmd0aCkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkKCiMjIyNjb21wYXJlIGxpYnJhcnkgY2FwdHVyZSBwb29sIyMjIwoKY29sczMgPC0gYygiIzIyODgzMyIsICIjQUEzMzc3IikKCmZhY2V0X25hbWVzIDwtIGMoImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICAgICAgICAgICAgICAgICJub2RlZHVwX1RFIiA9ICJOb24tRGVkdXBsaWNhdGVkIikKCm1ldGFkYXRhMyA8LSAKICBtZXRhZGF0YSB8PgogIHNlbGVjdChTYW1wbGUuSUQsIFBvb2wuZm9yLnNlcXVlbmNpbmcpIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUG9vbCA9IFBvb2wuZm9yLnNlcXVlbmNpbmcpCgpjb3VudHNfcG9vbCA8LSBsZWZ0X2pvaW4oY291bnRzX3JlYWRzX25vcm0sIG1ldGFkYXRhMywgYnkgPSAiU2FtcGxlX2lkIikKCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3J9Cgpwb29sX2NvdW50c19zdW0gPC0gCiAgY291bnRzX3Bvb2wgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IGFzLmNoYXJhY3RlcihWaXJhbC5sb2FkKSwKICAgIHkgPSBsb2cxMChtYXRjaGVkKSwKICAgIGNvbG91ciA9IFBvb2wKICApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHlsYWIoIkxvZyAoVmlyYWwgUmVhZHMpIikgKyB4bGFiKCJMb2cgKFZpcmFsIGxvYWQpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMywgbGFiZWxzID0gYygiUG9vbCAxIiwgIlBvb2wgMiIpKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYyhicXVvdGUoMTBeezJ9KSwgYnF1b3RlKDEwXnszfSksIGJxdW90ZSgxMF57NX0pKSkKICAKCiMgcG9vbF9yZWFkY291bnRzX25vcm0gPC0gCiMgICBjb3VudHNfcG9vbCB8PgojICAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KIyAgIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KIyAgIGdncGxvdChhZXMoeCA9IHZpcnVzLCB5ID0gbG9nMTAobm9ybV9jb3VudHMxKSkpICsKIyAgIGdlb21fYm94cGxvdCgpICsKIyAgIGZhY2V0X2dyaWQoUG9vbCB+IHR5cGUpICsKIyAgIHRoZW1lX2ZldygpICsKIyAgIHRoZW1lKAojICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiMgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAojICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAojICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiMgICApICsKIyAgIHlsYWIoImxvZzEwKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMpIikKCnBvb2xfbm9ybTFfc3VtIDwtIAogIGNvdW50c19wb29sIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCksCiAgICB5ID0gbG9nMTAobWF0Y2hlZCksCiAgICBjb2xvdXIgPSBQb29sCiAgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikgCiAgKSArCiAgeWxhYigibG9nMTAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcykiKSArIHhsYWIoIkxvZyAoVmlyYWwgbG9hZCkiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMzLCBsYWJlbHMgPSBjKCJQb29sIDEiLCAiUG9vbCAyIikpICsgCiAgICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoYnF1b3RlKDEwXnsyfSksIGJxdW90ZSgxMF57M30pLCBicXVvdGUoMTBeezV9KSkpCgojIHBvb2xfcmVhZGNvdW50c19ub3JtMiA8LSAKIyAgIGNvdW50c19wb29sIHw+CiMgICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgojICAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgojICAgZ2dwbG90KGFlcyh4ID0gdmlydXMsIHkgPSBsb2cxMChub3JtX2NvdW50czIpKSkgKwojICAgZ2VvbV9ib3hwbG90KCkgKwojICAgZmFjZXRfZ3JpZChQb29sIH4gdHlwZSkgKwojICAgdGhlbWVfZmV3KCkgKwojICAgdGhlbWUoCiMgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKIyAgICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKIyAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiMgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiMgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKIyAgICkgKwojICAgeWxhYigibG9nMTAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcy9nZW5vbWUgbGVuZ3RoKSIpCgoKcG9vbF9ub3JtMl9zdW0gPC0gCiAgY291bnRzX3Bvb2wgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IGFzLmNoYXJhY3RlcihWaXJhbC5sb2FkKSwKICAgIHkgPSBsb2cxMChtYXRjaGVkKSwKICAgIGNvbG91ciA9IFBvb2wKICApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHlsYWIoImxvZzEwKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMvZ2Vub21lIGxlbmd0aCkiKSArIHhsYWIoIkxvZyAoVmlyYWwgbG9hZCkiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMzLCBsYWJlbHMgPSBjKCJQb29sIDEiLCAiUG9vbCAyIikpICsgCiAgICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoYnF1b3RlKDEwXnsyfSksIGJxdW90ZSgxMF57M30pLCBicXVvdGUoMTBeezV9KSkpCgoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGRlcHRoIGZpbGVzCgpkZXB0aF9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKZGVwdGhfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aHNfYnRfYWxsIDwtIHJiaW5kKGRlcHRoX2RlZHVwX2J0LCBkZXB0aF9ub2RlZHVwX2J0KQoKZGVwdGhzX3JlYWRzIDwtIAogIGxlZnRfam9pbihkZXB0aHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpIHw+CiAgbXV0YXRlKGdlbm9tZV9zdHJ1Y3R1cmUgPSBjYXNlX3doZW4oKAogICAgdmlydXMgPT0gIkh1bWFuX2FkZW5vdmlydXNfNDAiIHwKICAgICAgdmlydXMgPT0gIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIKICApIH4gIkROQSIsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgpkZXB0aHNfcG9vbCA8LSBsZWZ0X2pvaW4oZGVwdGhzX3JlYWRzLCBtZXRhZGF0YTMsIGJ5ID0gIlNhbXBsZV9pZCIpCgojIHBvb2xfcmVhZGRlcHRocyA8LSAKIyAgIGRlcHRoc19wb29sIHw+CiMgICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgojICAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgojICAgZ2dwbG90KGFlcyh4ID0gdmlydXMsIHkgPSBsb2cxMChtZWFuX2RlcHRoKSkpICsKIyAgIGdlb21fYm94cGxvdCgpICsKIyAgIGZhY2V0X2dyaWQoUG9vbCB+IHR5cGUpICsKIyAgIHRoZW1lX2ZldygpICsKIyAgIHRoZW1lKAojICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiMgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiMgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAojICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAojICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiMgICApICsKIyAgIHlsYWIoIkxvZyAobWVhbiByZWFkIGRlcHRoKSIpCgpwb29sX2RlcHRoc19zdW0gPC0KICBkZXB0aHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG1lYW5fZGVwdGgpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgeWxhYigiTG9nIChtZWFuIHJlYWQgZGVwdGgpIikgKwogIHhsYWIoIkxvZyAoVmlyYWwgbG9hZCkiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYyhicXVvdGUoMTBeezJ9KSwgYnF1b3RlKDEwXnszfSksIGJxdW90ZSgxMF57NX0pKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMywgbGFiZWxzID0gYygiUG9vbCAxIiwgIlBvb2wgMiIpKQoKCmBgYAoKIyMjICoqKkZpbmFsIHBsb3QqKioKYGBge3J9CmdnYXJyYW5nZSgKICBwb29sX2NvdW50c19zdW0sCiAgcG9vbF9ub3JtMV9zdW0sCiAgcG9vbF9ub3JtMl9zdW0sCiAgcG9vbF9kZXB0aHNfc3VtLAogIG5yb3cgPSAyLAogIG5jb2wgPSAyLAogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLCAKICBhbGlnbiA9ICJodiIKKQoKCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9wb29sX2NvbXBhcmVfdmlydXNlc19zdW0ucG5nIix3aWR0aD0xMCxoZWlnaHQ9NykKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzIucGRmIiwKICAgICAgIHdpZHRoID0gMTAsCiAgICAgICBoZWlnaHQgPSA3KQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMi5wbmciLAogICAgICAgd2lkdGggPSAxMCwKICAgICAgIGhlaWdodCA9IDcpCgpgYGAKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRmlndXJlIFMzCmBgYHtyfQoKIyNwbG90cyBvZiByZWFkIGNvdW50cyBhbmQgdmlyYWwgcmVhZCBjb3VudHMKI05vdmVtYmVyIDIwMjQKCiNtZXRhZGF0YQoKbWV0YWRhdGEgPC0KICByZWFkLmNzdigKICAgICJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKbWV0YWRhdGEyIDwtIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCgojaW1wb3J0IHJlYWQgY291bnQgZmlsZXMKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX25vZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKI2ltcG9ydCB2aXJhbCByZWFkcyBtYXBwZWQgKHRvIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucykKCnZpcmFsX3JlYWRzX2RlZHVwIDwtCiAgcmVhZC5jc3YoCiAgICAiZGF0YV9URS90b3RhbF92aXJ1c19tYXBwZWRfcmVhZHNfcGVyX3NhbXBsZV9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwOC5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCnZpcmFsX3JlYWRzX25vZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL3RvdGFsX3ZpcnVzX21hcHBlZF9yZWFkc19wZXJfc2FtcGxlX25vZGVkdXBfYXRjY19yZWZfMjAyNDExMDguY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb2xzMiA8LSBjKCIjQkI1NTY2IiwgIiMwMDQ0ODgiKQoKZmFjZXRfbmFtZXMgPC0gYygiZGVkdXBfVEUiID0gIkRlZHVwbGljYXRlZCIsCiAgICAgICAgICAgICAgICAgIm5vZGVkdXBfVEUiID0gIk5vbi1EZWR1cGxpY2F0ZWQiKQoKcmVhZHNfbWV0YWRhdGFfZGVkdXAgPC0KICBsZWZ0X2pvaW4oY291bnRzX2RlZHVwX2J0LCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgpyZWFkc192aXJhbF9kZWR1cCA8LQogIGxlZnRfam9pbihyZWFkc19tZXRhZGF0YV9kZWR1cCwgdmlyYWxfcmVhZHNfZGVkdXAsIGJ5ID0gIlNhbXBsZV9pZCIpCgpyZWFkc19tZXRhZGF0YV9ub2RlZHVwIDwtCiAgbGVmdF9qb2luKGNvdW50c19ub2RlZHVwX2J0LCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgpyZWFkc192aXJhbF9ub2RlZHVwIDwtCiAgbGVmdF9qb2luKHJlYWRzX21ldGFkYXRhX25vZGVkdXAsIHZpcmFsX3JlYWRzX25vZGVkdXAsIGJ5ID0gIlNhbXBsZV9pZCIpCgpyZWFkc192aXJhbF9hbGwgPC0gcmJpbmQocmVhZHNfdmlyYWxfZGVkdXAsIHJlYWRzX3ZpcmFsX25vZGVkdXApCgoKcmVhZHNfcGxvdCA8LSAKICByZWFkc192aXJhbF9hbGwgfD4KICBncm91cF9ieShCYWNrZ3JvdW5kLCBTYW1wbGVfaWQsIFZpcmFsLmxvYWQsIHR5cGUpIHw+CiAgc3VtbWFyaXNlKAogICAgdG90YWxfcmVhZHMgPSAoUUNfcmVhZHMgKiAyKSwKICAgIHZpcmFsX3JlYWRzID0gdG90YWxfdmlydXNfcmVhZHMsCiAgICBBVENDX3JlYWRzID0gc3VtKG1hdGNoZWQpLAogICAgcHJvcF9BVENDID0gQVRDQ19yZWFkcyAvIHRvdGFsX3JlYWRzLAogICAgcHJvcF92aXJhbCA9IHRvdGFsX3ZpcnVzX3JlYWRzIC8gdG90YWxfcmVhZHMsCiAgICBkaWZmID0gdmlyYWxfcmVhZHMgLSBBVENDX3JlYWRzCiAgKSB8PgogIHVuaXF1ZSgpCgpgYGAKCiMjIyBNYWtlIHBsb3RzCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKdG90YWxfcmVhZHMgPC0gCiAgcmVhZHNfcGxvdCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSAodG90YWxfcmVhZHMpLAogICAgY29sb3VyID0gQmFja2dyb3VuZAogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IEJhY2tncm91bmQpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyAKICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIHhsYWIoIlZpcmFsIGxvYWQiKSArCiAgIyBnZ3RpdGxlKCJBbGwiKSArCiAgeWxhYigiVG90YWwgbnVtYmVyIG9mIHJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKCnZpcmFsX3JlYWRzIDwtIAogIHJlYWRzX3Bsb3QgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gKHZpcmFsX3JlYWRzKSwKICAgIGNvbG91ciA9IEJhY2tncm91bmQKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBCYWNrZ3JvdW5kKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyB4bGFiKCJWaXJhbCBsb2FkIikgKwogICMgZ2d0aXRsZSgiVmlyYWwgcmVhZHMiKSArCiAgeWxhYigiTnVtYmVyIG9mIHZpcmFsIHJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKCkFUQ0NfcmVhZHMgPC0gCiAgcmVhZHNfcGxvdCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSAoQVRDQ19yZWFkcyksCiAgICBjb2xvdXIgPSBCYWNrZ3JvdW5kCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gQmFja2dyb3VuZCksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIAogICAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgeGxhYigiVmlyYWwgbG9hZCIpICsKICBnZ3RpdGxlKCJTcGlrZS1pbiBWaXJhbCBSZWFkcyIpICsKICB5bGFiKCJTcGlrZS1pbiBWaXJhbCBSZWFkcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIlAxIiwgIlAyIikpCgpwcm9wX0FUQ0MgPC0gcmVhZHNfcGxvdCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoeCA9IFZpcmFsLmxvYWQsIHkgPSBwcm9wX0FUQ0MsIGNvbG91ciA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBCYWNrZ3JvdW5kKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyB4bGFiKCJWaXJhbCBsb2FkIikgKwogIGdndGl0bGUoIlNwaWtlLWluIHZpcmFsIHJlYWRzIikgKwogIHlsYWIoIlByb3BvcnRpb24iKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJQMSIsICJQMiIpKQoKcHJvcF92aXJhbCA8LSByZWFkc19wbG90IHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gVmlyYWwubG9hZCwgeSA9IHByb3BfdmlyYWwsIGNvbG91ciA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBCYWNrZ3JvdW5kKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyB4bGFiKCJWaXJhbCBsb2FkIikgKwogICMgZ2d0aXRsZSgiVmlyYWwgcmVhZHMiKSArCiAgeWxhYigiUHJvcG9ydGlvbiBvZiB2aXJhbCByZWFkcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIlAxIiwgIlAyIikpICsgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsMS4wKSkKCgojZ2dhcnJhbmdlKHRvdGFsX3JlYWRzLHZpcmFsX3JlYWRzLEFUQ0NfcmVhZHMscHJvcF92aXJhbCxwcm9wX0FUQ0MsbnJvdz0yLG5jb2w9Myxjb21tb24ubGVnZW5kID0gVFJVRSkKCmBgYAoKIyMjICoqKkZpbmFsIHBsb3QqKioKYGBge3IsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgpnZ2FycmFuZ2UodG90YWxfcmVhZHMsCiAgICAgICAgICB2aXJhbF9yZWFkcywKICAgICAgICAgIHByb3BfdmlyYWwsCiAgICAgICAgICBucm93ID0gMywKICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogICAgICAgICAgYWxpZ24gPSAiaHYiKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL2JhY2tncm91bmRzX3JlYWRzLnBuZyIpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1MzLnBkZiIsIAogICAgICAgd2lkdGggPSA4LAogICAgICAgaGVpZ2h0ID0gOCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzMucG5nIiwgCiAgICAgICB3aWR0aCA9IDgsCiAgICAgICBoZWlnaHQgPSA4KQoKIyMjI2NvbXBhcmUgcHJvcG9ydGlvbiB2aXJhbCByZWFkcyBwZXIgcG9vbCB3aXRoIHNob3RndW4jIyMjCgojIG1ldGFkYXRhMyA8LSBtZXRhZGF0YSB8PgojICAgc2VsZWN0KFNhbXBsZS5JRCwKIyAgICAgICAgICBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuLAojICAgICAgICAgIFBvb2wuZm9yLnNlcXVlbmNpbmcpIHw+CiMgICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgojICAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKIyAKIyByZWFkc192aXJhbF9kZWR1cDMgPC0KIyAgIGZ1bGxfam9pbihtZXRhZGF0YTMsIHZpcmFsX3JlYWRzX2RlZHVwLCBieSA9ICJTYW1wbGVfaWQiKQojIAojIHJlYWRzX3ZpcmFsX25vZGVkdXAzIDwtCiMgICBmdWxsX2pvaW4obWV0YWRhdGEzLCB2aXJhbF9yZWFkc19ub2RlZHVwLCBieSA9ICJTYW1wbGVfaWQiKQojIAojIHJlYWRzX3ZpcmFsX2RlZHVwMyB8PgojICAgZ3JvdXBfYnkoUG9vbC5mb3Iuc2VxdWVuY2luZykgfD4KIyAgIHN1bW1hcmlzZSgKIyAgICAgdmlyYWxfcmVhZHMgPSBzdW0odG90YWxfdmlydXNfcmVhZHMpLAojICAgICB0b3RhbF9yZWFkcyA9IHN1bShRQ19yZWFkcyAqIDIpLAojICAgICBwcm9wX3ZpcmFsID0gdmlyYWxfcmVhZHMgLyB0b3RhbF9yZWFkcwojICAgKQojIAojIHBvbHlvbWljcyA8LQojICAgcmVhZC5jc3YoCiMgICAgICJkYXRhX3BvbHlvbWljcy90b3RhbF92aXJ1c19tYXBwZWRfcmVhZHNfcGVyX3NhbXBsZV9kZWR1cC5jc3YiCiMgICApCiMgCiMgI3JlYWQgZGF0YSBmcm9tIHBvbHlvbWljc19pbmRleGVzX3N0ZWZhbm8gZG9jdW1lbnQKIyB0b3RhbF9yZWFkcyA8LSBkYXRhLmZyYW1lKHRvdGFsX3JlYWRzID0gYyg1OTQyNzYwLCA3NzE0Mjc1KSkKIyAKIyBrZWVwcyA8LSBjKCJSTkEtTXNwLXAyIiwgIlJOQS1Nc3AtcDgiKQojIAojIHBvbHlvbWljc19yZWFkX3Byb3AgPC0gcG9seW9taWNzIHw+CiMgICBmaWx0ZXIoU2FtcGxlX2lkICVpbiUga2VlcHMpCiMgCiMgcG9seW9taWNzX3JlYWRfcHJvcDIgPC0gY2JpbmQocG9seW9taWNzX3JlYWRfcHJvcCwgdG90YWxfcmVhZHMpCiMgCiMgcG9seW9taWNzX3JlYWRfcHJvcDIgfD4KIyAgIHN1bW1hcmlzZShwcm9wX3ZpcmFsID0gdG90YWxfdmlydXNfcmVhZHMgLyB0b3RhbF9yZWFkcykKCmBgYAoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBObyBsb25nZXIgcmVxdWlyZWQ/IEZpZ3VyZSBTNAoKIyMjIE1ha2UgcGxvdHMKYGBge3J9CiMjIyNyZWFkIGNvdW50cy9kZXB0aHMgc3BsaXQgYnkgYmFja2dyb3VuZCMjIyMKCiNjaGFuZ2UgbGFiZWxzIGluIGZhY2V0IHBsb3RzCgpmYWNldF9uYW1lc19iZyA8LSBjKAogICJkZWR1cF9URSIgPSAiRGVkdXBsaWNhdGVkIiwKICAibm9kZWR1cF9URSIgPSAiTm9uLURlZHVwbGljYXRlZCIsCiAgInAyIiA9ICJQMSIsCiAgInA4IiA9ICJQMiIKKQoKI2JyZWFrIGRvd24gYnkgQmFja2dyb3VuZCB4IHZpcnVzCgpiYWNrZ3JvdW5kX2NvdW50c19yZWFkcyA8LSAKICBjb3VudHNfcmVhZHNfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2cxMChtYXRjaGVkKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKEJhY2tncm91bmQgfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzX2JnKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0KICAgICAgYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICAgICkKICApICsKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfbG9nMTAoKSkgKwogIHlsYWIoImxvZzEwKFZpcmFsIFJlYWRzKSIpCgpiYWNrZ3JvdW5kc19jb3VudHNfcmVhZHNfbm9ybSA8LSAKICBjb3VudHNfcmVhZHNfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2cxMChub3JtX2NvdW50czEpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoQmFja2dyb3VuZCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXNfYmcpKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICBzY2FsZV94X2xvZzEwKGxhYmVsID0gc2NhbGVzOjpsYWJlbF9sb2cxMCgpKSArCiAgeWxhYigibG9nMTAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcykiKQoKYmFja2dyb3VuZHNfY291bnRzX3JlYWRzX25vcm0yIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG5vcm1fY291bnRzMiksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZChCYWNrZ3JvdW5kIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lc19iZykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2cxMCgpKSArCiAgeWxhYigibG9nMTAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcy9nZW5vbWUgbGVuZ3RoKSIpCgpiYWNrZ3JvdW5kX3JlYWRfZGVwdGhzIDwtIAogIGRlcHRoc19yZWFkcyB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2cxMChtZWFuX2RlcHRoKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKEJhY2tncm91bmQgfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzX2JnKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbCA9IHNjYWxlczo6bGFiZWxfbG9nMTAoKSkgKwogIHlsYWIoImxvZzEwKG1lYW4gcmVhZCBkZXB0aCkiKQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKiAKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NiwgZmlnLmhlaWdodD04fQoKZ2dhcnJhbmdlKAogIGJhY2tncm91bmRfY291bnRzX3JlYWRzLAogIGJhY2tncm91bmRzX2NvdW50c19yZWFkc19ub3JtLAogIGJhY2tncm91bmRzX2NvdW50c19yZWFkc19ub3JtMiwKICBiYWNrZ3JvdW5kX3JlYWRfZGVwdGhzLAogIG5yb3cgPSAyLAogIG5jb2wgPSAyLAogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogIGFsaWduID0gImh2IgopCgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvYmFja2dyb3VuZHNfcmVhZF9jb3VudF9kZXB0aC5wbmciLHdpZHRoPTEwLGhlaWdodD03KQoKI2dnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZXNfcGRmL0ZpZ3VyZVM0LnBkZiIsd2lkdGg9MTAsaGVpZ2h0PTcpCgpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyA+Pj4gRmlndXJlIDI6IHBsb3RzIG9mIFRFIGV4cGVyaW1lbnQgZGF0YSAtIGdlbm9tZSBjb3ZlcmFnZSAmIHBlciBzaXRlIGNvdmVyYWdlCgojIyMgUmVhZC1pbiBkYXRhCmBgYHtyfQoKI3Bsb3RzIG9mIFRFIGV4cGVyaW1lbnQgZGF0YSAtIGdlbm9tZSBjb3ZlcmFnZSAmIHBlciBzaXRlIGNvdmVyYWdlCiNhbHNvIHNlcGFyYXRlZCBieSB2aXJ1c2VzCiNBVENDIGdlbm9tZXMgdXBkYXRlZCB2ZXJzaW9uCiNPY3RvYmVyIDIwMjQKCiN1c2UgYm93dGllMiBkYXRhCgojIyMjZ2Vub21lIGNvdmVyYWdlIyMjIwoKdW56aXAoemlwZmlsZSA9ICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdi56aXAiLCBleGRpciA9ICJkYXRhX1RFLyIpCgp1bnppcCh6aXBmaWxlID0gImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YuemlwIiwgZXhkaXIgPSAiZGF0YV9URS8iKQoKZGVkdXBfcGVyX3NpdGUgPC0KICByZWFkX3RzdigKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIKICApCgoKbm9kZWR1cF9wZXJfc2l0ZSA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiCiAgKQoKZmlsZS5yZW1vdmUoImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IikKCmZpbGUucmVtb3ZlKCAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zaXRlX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIpCgojYWRkIGxlbmd0aCBjb2x1bW4gZnJvbSByZWFkIGRlcHRoIGZpbGUgdG8gcGVyIHNpdGUgZmlsZQoKI21ldGFkYXRhCgptZXRhZGF0YSA8LQogIHJlYWQuY3N2KAogICAgIm1ldGFkYXRhL3NhbXBsZUlEc19URVNwaWtlSW4uY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgptZXRhZGF0YTIgPC0gCiAgbWV0YWRhdGEgfD4KICBzZWxlY3QoU2FtcGxlLklELCBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKSB8PgogIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKCiNpbXBvcnQgYW5kIGNvbWJpbmUgcmVhZCBjb3VudCBmaWxlcwoKI2RlZHVwbGljYXRlZCBhbmQgbm9uLWRlZHVwbGljYXRlZAoKY291bnRzX2RlZHVwX2J0IDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmNvdW50c19ub2RlZHVwX2J0IDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiCiAgKQoKY291bnRzX2J0X2FsbCA8LSByYmluZChjb3VudHNfZGVkdXBfYnQsIGNvdW50c19ub2RlZHVwX2J0KQoKY291bnRzX3JlYWRzIDwtIGxlZnRfam9pbihjb3VudHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgpgYGAKCiMjIyBGb3JtYXQgZGF0YQpgYGB7cn0KI25vcm1hbGlzZSBieSBib3RoIHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoIC0gc2hvdWxkIGJlIHRoZSBzYW1lIGFzIG1lYW4gcmVhZCBkZXB0aAoKY291bnRzX3JlYWRzX25vcm0gPC0gCiAgY291bnRzX3JlYWRzIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMSA9IG1hdGNoZWQgLyBRQ19yZWFkcykgfD4KICBtdXRhdGUobm9ybV9jb3VudHMyID0gbWF0Y2hlZCAvIFFDX3JlYWRzIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShub3JtX2NvdW50czMgPSBtYXRjaGVkIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShnZW5vbWVfc3RydWN0dXJlID0gY2FzZV93aGVuKCgKICAgIHZpcnVzID09ICJIdW1hbl9hZGVub3ZpcnVzXzQwIiB8CiAgICAgIHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiCiAgKSB+ICJETkEiLAogIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKbGVuZ3RocyA8LSAKICBjb3VudHNfcmVhZHNfbm9ybSB8PgogIHNlbGVjdCh2aXJ1cywgbGVuZ3RoKSB8PgogIGRpc3RpbmN0KCkKCiNjYWxjdWxhdGUgZ2Vub21lIGNvdmVyYWdlCgpwZXJzaXRlX2NvdmVyYWdlX2RlZHVwIDwtIAogIGRlZHVwX3Blcl9zaXRlIHw+CiAgcmVuYW1lKFZpcmFsLmxvYWQgPSBgVmlyYWwgbG9hZGApIHw+CiAgZ3JvdXBfYnkoU2FtcGxlX2lkLCB2aXJ1cywgVmlyYWwubG9hZCwgQmFja2dyb3VuZCwgdHlwZSkgfD4KICBmaWx0ZXIoY292ZXJhZ2UgPiAwKSB8PgogIHN1bW1hcmlzZShnZW5vbWVfY292ZXJhZ2UgPSBuKCkpIHw+CiAgbGVmdF9qb2luKGxlbmd0aHMpIHw+CiAgbXV0YXRlKHBlcmNlbnRfY292ZXJhZ2UgPSBnZW5vbWVfY292ZXJhZ2UgLyBsZW5ndGgpCgpwZXJzaXRlX2NvdmVyYWdlX25vZGVkdXAgPC0gCiAgbm9kZWR1cF9wZXJfc2l0ZSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdyb3VwX2J5KFNhbXBsZV9pZCwgdmlydXMsIFZpcmFsLmxvYWQsIEJhY2tncm91bmQsIHR5cGUpIHw+CiAgZmlsdGVyKGNvdmVyYWdlID4gMCkgfD4KICBzdW1tYXJpc2UoZ2Vub21lX2NvdmVyYWdlID0gbigpKSB8PgogIGxlZnRfam9pbihsZW5ndGhzKSB8PgogIG11dGF0ZShwZXJjZW50X2NvdmVyYWdlID0gZ2Vub21lX2NvdmVyYWdlIC8gbGVuZ3RoKQoKcGVyc2l0ZV9jb3ZlcmFnZV9ib3RoIDwtCiAgcmJpbmQocGVyc2l0ZV9jb3ZlcmFnZV9kZWR1cCwgCiAgICAgICAgcGVyc2l0ZV9jb3ZlcmFnZV9ub2RlZHVwKQoKY292ZXJhZ2VfbGFiZWxzIDwtIGMoIjAiID0gIkNvbnRyb2wiLAogICAgICAgICAgICAgICAgICAgICAiMTAwIiA9ICIxMF57Mn0iLAogICAgICAgICAgICAgICAgICAgICAiMTAwMCIgPSAiMTBeezN9IiwKICAgICAgICAgICAgICAgICAgICAgIjEwMDAwIiA9ICIxMF57NX0iLAogICAgICAgICAgICAgICAgICAgICAiZGVkdXBfVEUiID0gIkRlZHVwbGljYXRlZCIsCiAgICAgICAgICAgICAgICAgICAgICJub2RlZHVwX1RFIj0gIk5vbi1EZWR1cGxpY2F0ZWQiKQoKY292ZXJhZ2VfbGFiZWxzMiA8LSBjKCIwIiA9ICJDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICIxMDAiID0gIjEwXnsyfSIsCiAgICAgICAgICAgICAgICAgICAgICAiMTAwMCIgPSAiMTBeezN9IiwKICAgICAgICAgICAgICAgICAgICAgICIxMDAwMCIgPSAiMTBeezV9IikKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7ciwgZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02fQoKY29sczIgPC0gYygiI0JCNTU2NiIsCiAgICAgICAgICAgIiMwMDQ0ODgiKQoKY29sczQgPC0gYygiI0REQUEzMyIsCiAgICAgICAgICAgIiNCQjU1NjYiLAogICAgICAgICAgICIjMDA0NDg4IikKCgpwZXJzaXRlX2NvdmVyYWdlX2JvdGgkVmlyYWwubG9hZCA8LSBmYWN0b3IocGVyc2l0ZV9jb3ZlcmFnZV9ib3RoJFZpcmFsLmxvYWQsIGxhYmVscyA9IGMoIjAiLAogICAgIjEwXnsyfSIsIAogICAgIjEwXnszfSIsIAogICAgIjEwXns1fSIKICAgICkpCgoKIyNhcmUgdGhlIGRlZHVwbGljYXRlZCBhbmQgbm9uIGRlZHVwbGljYXRlZCBkYXRhc2V0cyBpZGVudGljYWw/PwojI2lmIHRoZXkgYXJlIHRoZSBzYW1lIGNhbiBtYXliZSBqdXN0IHNob3cgb25lCiNzaG93IGRlZHVwbGljYXRlZAoKcGVyc2l0ZV9jb3ZlcmFnZV9ib3RoIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBnZ3Bsb3QoYWVzKHggPSB2aXJ1cywgeSA9IHBlcmNlbnRfY292ZXJhZ2UsIGNvbG91ciA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC43NSkpICsKICBmYWNldF9ncmlkKH5hcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCksIGxhYmVsbGVyID0gbGFiZWxfcGFyc2VkKSArCiAgdGhlbWVfZmV3KCkgKwogIHlsYWIoIkdlbm9tZSBjb3ZlcmFnZSIpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIlAxIiwgIlAyIikpICsKICBzY2FsZV94X2Rpc2NyZXRlKAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMSkpCgpgYGAKCiMjIyAqKipGaW5hbCBwbG90KioqCmBgYHtyLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9nZW5vbWVfY292X2RlZHVwb25seS5wbmciLHdpZHRoPTE1LGhlaWdodD02KQoKZ2dzYXZlKAogICJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV8yLnBkZiIsCiAgd2lkdGggPSAxNSwKICBoZWlnaHQgPSA2CikKCmdnc2F2ZSgKICAiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfMi5wbmciLAogIHdpZHRoID0gMTUsCiAgaGVpZ2h0ID0gNgopCgoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM0CmBgYHtyfQoKcGVyc2l0ZV9ib3RoIDwtIHJiaW5kKGRlZHVwX3Blcl9zaXRlLCBub2RlZHVwX3Blcl9zaXRlKQoKcGVyc2l0ZV9yZWFkcyA8LSBsZWZ0X2pvaW4ocGVyc2l0ZV9ib3RoLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgpwZXJzaXRlX25vcm0gPC0gcGVyc2l0ZV9yZWFkcyB8PgogIG11dGF0ZShub3JtX2NvdiA9IGNvdmVyYWdlIC8gUUNfcmVhZHMpCgpjb3ZlcmFnZV9sYWJlbHMzIDwtYygiMTAwIiA9ICIxZSswMiIsCiAgICAgICAgICAgICAgICAgICAgIjEwMDAiID0gIjFlKzAzIiwKICAgICAgICAgICAgICAgICAgICAiMTAwMDAwIiA9ICIxZSswNSIsCiAgICAgICAgICAgICAgICAgICAgInAyIiA9ICJQMSIsCiAgICAgICAgICAgICAgICAgICAgInA4Ij0gIlAyIikKCnBlcnNpdGVfbm9ybSRgVmlyYWwgbG9hZGAgPC0gCiAgZmFjdG9yKHBlcnNpdGVfbm9ybSRgVmlyYWwgbG9hZGAsIAogICAgICAgICBsYWJlbHMgPSBjKCIwIiwKICAgICAgICAgICAgICAgICAgICAiMTBeezJ9IiwgCiAgICAgICAgICAgICAgICAgICAgIjEwXnszfSIsCiAgICAgICAgICAgICAgICAgICAgIjEwXns1fSIpKQoKCnBlcnNpdGVfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKHZpcnVzID09ICJIdW1hbl9yZXNwaXJhdG9yeV9zeW5jeXRpYWxfdmlydXMiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoeCA9IHNpdGUsIHkgPSBjb3ZlcmFnZSwgZmlsbCA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcChWaXJhbC5sb2FkIH4gU2FtcGxlX2lkLCBsYWJlbCA9IGxhYmVsX3BhcnNlZCkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIGdndGl0bGUoIkh1bWFuIFJTViAoZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCYWNrZ3JvdW5kIikpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiUDEiLCAiUDIiKSkKYGBgCgojIyMjICoqKkZpbmFsIHBsb3QqKioKYGBge3J9Cmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzQucGRmIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TNC5wbmciLAogICAgICAgd2lkdGg9MTUsCiAgICAgICBoZWlnaHQ9MTApCmBgYAoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTNQpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0KCnBlcnNpdGVfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKHZpcnVzID09ICJaaWthX3ZpcnVzIikgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBnZ3Bsb3QoYWVzKHggPSBzaXRlLCB5ID0gY292ZXJhZ2UsIGZpbGwgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X3dyYXAoVmlyYWwubG9hZCB+IFNhbXBsZV9pZCwgbGFiZWwgPSBsYWJlbF9wYXJzZWQpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICBnZ3RpdGxlKCJaaWthIHZpcnVzIChkZWR1cGxpY2F0ZWQpIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkJhY2tncm91bmQiKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJQMSIsICJQMiIpKQoKYGBgCgojIyMjKioqRmluYWwgcGxvdCoqKgpgYGB7cn0KCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzUucGRmIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TNS5wbmciLAogICAgICAgd2lkdGg9MTUsCiAgICAgICBoZWlnaHQ9MTApCgpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzYKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9CgpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIpIHw+CiAgcmVuYW1lKFZpcmFsLmxvYWQgPSBgVmlyYWwgbG9hZGApIHw+CiAgZ2dwbG90KGFlcyh4ID0gc2l0ZSwgeSA9IGNvdmVyYWdlLCBmaWxsID0gQmFja2dyb3VuZCkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQsIGxhYmVsID0gbGFiZWxfcGFyc2VkKSArCiAgeWxhYigiQ292ZXJhZ2UiKSArCiAgZ2d0aXRsZSgiSHVtYW4gQWRlbm92aXJ1cyAoZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCYWNrZ3JvdW5kIikpICsKIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJQMSIsICJQMiIpKQoKYGBgCgojIyMjKioqRmluYWwgcGxvdCoqKgpgYGB7cn0KCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzYucGRmIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TNi5wbmciLAogICAgICAgd2lkdGg9MTUsCiAgICAgICBoZWlnaHQ9MTApCgpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzcKYGBge3J9CkhCViA8LSAKcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIodmlydXMgPT0gIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIpIHw+CiAgcmVuYW1lKFZpcmFsLmxvYWQgPSBgVmlyYWwgbG9hZGApIHw+CiAgZ2dwbG90KGFlcyh4ID0gc2l0ZSwgeSA9IGNvdmVyYWdlLCBmaWxsID0gQmFja2dyb3VuZCkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQsIGxhYmVsID0gbGFiZWxfcGFyc2VkKSArCiAgeWxhYigiQ292ZXJhZ2UiKSArCiAgZ2d0aXRsZSgiSHVtYW4gQmV0YWhlcnBlc3ZpcnVzIChkZWR1cGxpY2F0ZWQpIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkJhY2tncm91bmQiKSkgKwogdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIlAxIiwgIlAyIikpCgpgYGAKCiMjIyMqKipGaW5hbCBwbG90KioqCmBgYHtyfQoKZ2dzYXZlKHBsb3QgPSBIQlYsIGZpbGU9ImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M3LnBkZiIsCiAgICAgICB3aWR0aD0xNSwKICAgICAgIGhlaWdodD0xMCwKICAgICAgIGRwaSA9IDYwMCkKCmdnc2F2ZShwbG90ID0gSEJWLCBmaWxlPSJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TNy5wbmciLAogICAgICAgd2lkdGg9MTUsCiAgICAgICBoZWlnaHQ9MTApCgoKYGBgCgoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTOApgYGB7cn0KI2hhdmUgdG8gZG8gdGhlc2UgZGlmZmVyZW50bHkgZHVlIHRvIHNlZ21lbnRhdGlvbgoKCkZMVV9NRTEgPC0gcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKHZpcnVzID09ICJJbmZsdWVuemFfQl92aXJ1cyIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCA9PSAicDIiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gc2l0ZSwKICAgIHkgPSBjb3ZlcmFnZSwKICAgIGZpbGwgPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCkKICApKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfZ3JpZChzZWcgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICBnZ3RpdGxlKCJJbmZsdWVuemEgQiB2aXJ1cyAoQmFja2dyb3VuZCAxIGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmlyYWwgbG9hZCIpKSArCiB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzNCwgbGFiZWwgPSBjKGV4cHJlc3Npb24oIjEwIl4iMiIpLCBleHByZXNzaW9uKCIxMCJeIjMiKSwgZXhwcmVzc2lvbigiMTAiXiI1IikpKQoKRkxVX01FMiA8LSBwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIodmlydXMgPT0gIkluZmx1ZW56YV9CX3ZpcnVzIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kID09ICJwMiIpIHw+CiAgcmVuYW1lKFZpcmFsLmxvYWQgPSBgVmlyYWwgbG9hZGApIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBzaXRlLAogICAgeSA9IGNvdmVyYWdlLAogICAgZmlsbCA9IGFzLmNoYXJhY3RlcihWaXJhbC5sb2FkKQogICkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF9ncmlkKHNlZyB+IFNhbXBsZV9pZCkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIGdndGl0bGUoIkluZmx1ZW56YSBCIHZpcnVzIChCYWNrZ3JvdW5kIDIgZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJWaXJhbCBsb2FkIikpICsKIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHM0LCBsYWJlbCA9IGMoZXhwcmVzc2lvbigiMTAiXiIyIiksIGV4cHJlc3Npb24oIjEwIl4iMyIpLCBleHByZXNzaW9uKCIxMCJeIjUiKSkpCgoKZ2dhcnJhbmdlKEZMVV9NRTEsIEZMVV9NRTIsIG5jb2wgPSAyLCBjb21tb24ubGVnZW5kID0gVFJVRSkKCmBgYAoKIyMjIyoqKkZpbmFsIHBsb3QqKioKYGBge3J9CgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M4LnBkZiIsCiAgICAgICB3aWR0aD0yMCwKICAgICAgIGhlaWdodD0xMiwKICAgICAgIGRwaT02MDApCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlX1M4LnBuZyIsCiAgICAgICB3aWR0aD0yMCwKICAgICAgIGhlaWdodD0xMikKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM5CmBgYHtyfQoKUkVPX01FMSA8LSAKICBwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIodmlydXMgPT0gIk1hbW1hbGlhbl9vcnRob3Jlb3ZpcnVzMyIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCA9PSAicDIiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gc2l0ZSwKICAgIHkgPSBjb3ZlcmFnZSwKICAgIGZpbGwgPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCkKICApKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfZ3JpZChzZWcgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJsb2cxMChDb3ZlcmFnZSkiKSArCiAgZ2d0aXRsZSgiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyAoQmFja2dyb3VuZCAxIGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmlyYWwgbG9hZCIpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczQsCiAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSBjKAogICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbigiMTAiIF4gIjIiKSwKICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24oIjEwIiBeICIzIiksCiAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uKCIxMCIgXiAiNSIpCiAgICAgICAgICAgICAgICAgICAgKSkKClJFT19NRTIgPC0gCiAgcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKHZpcnVzID09ICJNYW1tYWxpYW5fb3J0aG9yZW92aXJ1czMiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgPT0gInA4IikgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IHNpdGUsCiAgICB5ID0gY292ZXJhZ2UsCiAgICBmaWxsID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpCiAgKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X2dyaWQoc2VnIH4gU2FtcGxlX2lkKSArCiAgeWxhYigibG9nMTAoQ292ZXJhZ2UpIikgKwogIGdndGl0bGUoIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMgKEJhY2tncm91bmQgMiBkZWR1cGxpY2F0ZWQpIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIlZpcmFsIGxvYWQiKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzNCwKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IGMoCiAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uKCIxMCIgXiAiMiIpLAogICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbigiMTAiIF4gIjMiKSwKICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24oIjEwIiBeICI1IikKICAgICAgICAgICAgICAgICAgICApKQoKZ2dhcnJhbmdlKFJFT19NRTEsIFJFT19NRTIsIG5jb2wgPSAyLCBjb21tb24ubGVnZW5kID0gVFJVRSkKCmBgYAoKIyMjIyoqKkZpbmFsIHBsb3QqKioKYGBge3J9Cmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzkucGRmIiwKICAgICAgIHdpZHRoPTIwLAogICAgICAgaGVpZ2h0PTEyLAogICAgICAgZHBpPTYwMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzkucG5nIiwKICAgICAgIHdpZHRoPTIwLAogICAgICAgaGVpZ2h0PTEyLAogICAgICAgZHBpPTYwMCkKYGBgCgoKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjID4+Pj4gRmlndXJlIDM6IGFsbCB2aXJ1c2VzIC0gdGFyZ2V0IGFuZCBvZmYgdGFyZ2V0CgojIyMgUmVhZC1pbiBkYXRhCmBgYHtyfQoKIyByZWFkIGluIG1ldGFkYXRhCgptZXRhZGF0YSA8LQogIHJlYWQuY3N2KCJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsIGhlYWRlciA9IFRSVUUpCgptZXRhZGF0YTIgPC0KICBtZXRhZGF0YSB8PgogIHNlbGVjdCgKICAgIFNhbXBsZS5JRCwKICAgIEJhY2tncm91bmQuc2FtcGxlLAogICAgVmlyYWwubG9hZCwKICAgIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4KICApIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQoKI2ltcG9ydCB2aXJhbCByZWFkcyBtYXBwZWQgKHRvIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucykKCnZpcmFsX3JlYWRzX2RlZHVwIDwtCiAgcmVhZC5jc3YoCiAgICAiZGF0YV9URS90b3RhbF92aXJ1c19tYXBwZWRfcmVhZHNfcGVyX3NhbXBsZV9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwOC5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCnZpcmFsX3JlYWRzX25vZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL3RvdGFsX3ZpcnVzX21hcHBlZF9yZWFkc19wZXJfc2FtcGxlX25vZGVkdXBfYXRjY19yZWZfMjAyNDExMDguY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgojaW1wb3J0IGNvbnRpbmdlbmN5IHRhYmxlcwoKY29udGluZ2VuY3lfZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL2NvbnRpbmdlbmN5X3RhYmxlX21hcHBlZF92aXJ1c19yZWFkc19wZXJfZmFtaWx5X2dlbnVzX3NhbXBsZV9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwNi5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvbnRpbmdlbmN5X25vZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL2NvbnRpbmdlbmN5X3RhYmxlX21hcHBlZF92aXJ1c19yZWFkc19wZXJfZmFtaWx5X2dlbnVzX3NhbXBsZV9ub2RlZHVwX2F0Y2NfcmVmXzIwMjQxMTA2LmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY29udGFtaW5hbnRzIDwtCiAgYygiQmV0YWNvcm9uYXZpcnVzIiwgIkFscGhhaW5mbHVlbnphdmlydXMiLCAiR2FtbWFyZXRyb3ZpcnVzIikKCmBgYAoKIyMjIEZvcm1hdCBkYXRhCmBgYHtyfQoKIyBwaXZvdCBsb25nZXIgIApkZWR1cF9sb25nIDwtCiAgY29udGluZ2VuY3lfZGVkdXAgfD4KICBmaWx0ZXIoIWdlbnVzICVpbiUgY29udGFtaW5hbnRzKSB8PgogIGZpbHRlcihnZW51cyAhPSAiTkEiKSB8PgogIHBpdm90X2xvbmdlcihjb2xzID0gQTpQLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJTYW1wbGVfaWQiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSB8PgogIG11dGF0ZSgKICAgIHRhcmdldCA9IGNhc2Vfd2hlbigKICAgICAgZ2VudXMgPT0gIkN5Y2xvdmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICBnZW51cyA9PSAiQ2FyZGlvdmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICBnZW51cyA9PSAiS29idXZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgLmRlZmF1bHQgPSAib25fdGFyZ2V0IgogICAgKQogICkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoZ2VudXMgPT0gIk1hc3RhZGVub3ZpcnVzIiB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VudXMgPT0gIkN5dG9tZWdhbG92aXJ1cyIpIH4gIkROQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgpub19kZWR1cF9sb25nIDwtIGNvbnRpbmdlbmN5X25vZGVkdXAgfD4KICBmaWx0ZXIoIWdlbnVzICVpbiUgY29udGFtaW5hbnRzKSB8PgogIGZpbHRlcihnZW51cyAhPSAiTkEiKSB8PgogIHBpdm90X2xvbmdlcihjb2xzID0gQTpQLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJTYW1wbGVfaWQiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSB8PgogIG11dGF0ZSgKICAgIHRhcmdldCA9IGNhc2Vfd2hlbigKICAgICAgZ2VudXMgPT0gIkN5Y2xvdmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICBnZW51cyA9PSAiQ2FyZGlvdmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICBnZW51cyA9PSAiS29idXZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgLmRlZmF1bHQgPSAib25fdGFyZ2V0IgogICAgKQogICkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoZ2VudXMgPT0gIk1hc3RhZGVub3ZpcnVzIiB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VudXMgPT0gIkN5dG9tZWdhbG92aXJ1cyIpIH4gIkROQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgptZXRhZGF0YV9kZWR1cCA8LSBsZWZ0X2pvaW4oZGVkdXBfbG9uZywgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKZGVkdXBfdmlyYWxfcmVhZHMgPC0KICBsZWZ0X2pvaW4obWV0YWRhdGFfZGVkdXAsIHZpcmFsX3JlYWRzX2RlZHVwLCBieSA9ICJTYW1wbGVfaWQiKSB8PgogIG11dGF0ZSh0b3RhbF9yZWFkcyA9IFFDX3JlYWRzICogMikgfD4KICBtdXRhdGUocHJvcF90b3RhbCA9IGNvdW50IC8gdG90YWxfcmVhZHMpIHw+CiAgbXV0YXRlKHByb3BfdmlyYWwgPSBjb3VudCAvIHRvdGFsX3ZpcnVzX3JlYWRzKQoKbWV0YWRhdGFfbm9fZGVkdXAgPC0gbGVmdF9qb2luKG5vX2RlZHVwX2xvbmcsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCm5vZGVkdXBfdmlyYWxfcmVhZHMgPC0KICBsZWZ0X2pvaW4obWV0YWRhdGFfbm9fZGVkdXAsIHZpcmFsX3JlYWRzX25vZGVkdXAsIGJ5ID0gIlNhbXBsZV9pZCIpIHw+CiAgbXV0YXRlKHRvdGFsX3JlYWRzID0gUUNfcmVhZHMgKiAyKSB8PgogIG11dGF0ZShwcm9wX3RvdGFsID0gY291bnQgLyB0b3RhbF9yZWFkcykgfD4KICBtdXRhdGUocHJvcF92aXJhbCA9IGNvdW50IC8gdG90YWxfdmlydXNfcmVhZHMpCgpgYGAKCiMjIyBNYWtlIHBsb3RzCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFfQoKZmFjZXRfbmFtZXMgPC0gYygKICAiTXNwX3AyIiA9ICJQMSIsCiAgIk1zcF9wOCIgPSAiUDIiLAogICJvZmZfdGFyZ2V0IiA9ICJCYWNrZ3JvdW5kIiwKICAib25fdGFyZ2V0IiA9ICJTcGlrZS1pbiIKKQoKY29scyA8LQogIGMoCiAgICAiI0NDQkI0NCIsCiAgICAiIzMzMjI4OCIsCiAgICAiI0VFNzczMyIsCiAgICAiIzY2Q0NFRSIsCiAgICAiIzg4MjI1NSIsCiAgICAiIzQ0NzdBQSIsCiAgICAiI0FBMzM3NyIsCiAgICAiIzIyODgzMyIsCiAgICAiI0VFNjY3NyIKICApCgoKZGVkdXBfcmVhZHMgPC0gCiAgZGVkdXBfdmlyYWxfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk5lZ19jb250cm9sIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk1zcF9wNiIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKGNvdW50KSwKICAgIGNvbG91ciA9IGdlbnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ2VudXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKHRhcmdldCB+IEJhY2tncm91bmQuc2FtcGxlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsKICB5bGFiKCJWaXJhbCBSZWFkcyIpICsgCiAgeGxhYigiVmlyYWwgbG9hZCAoZ2MvbWwpIikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9Yygic29saWQiLCAiZG90dGVkIikpKyAKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkKCmRlZHVwX3Byb3BfdmlyYWwgPC0KICBkZWR1cF92aXJhbF9yZWFkcyB8PgogIGZpbHRlcihCYWNrZ3JvdW5kLnNhbXBsZSAhPSAiTmVnX2NvbnRyb2wiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kLnNhbXBsZSAhPSAiTXNwX3A2IikgfD4KICBnZ3Bsb3QoYWVzKHggPSBWaXJhbC5sb2FkLCB5ID0gcHJvcF92aXJhbCwgY29sb3VyID0gZ2VudXMpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBnZW51cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQodGFyZ2V0IH4gQmFja2dyb3VuZC5zYW1wbGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKyAKICBzY2FsZV94X2xvZzEwKCkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzPWMoInNvbGlkIiwgImRvdHRlZCIpKSsgCiAgeWxhYigiUHJvcG9ydGlvbiBvZiB2aXJhbCByZWFkcyIpICsKICB4bGFiKCJWaXJhbCBsb2FkIChnYy9tbCkiKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkKCmRlZHVwX3Byb3BfYWxsIDwtCiAgZGVkdXBfdmlyYWxfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk5lZ19jb250cm9sIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk1zcF9wNiIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gVmlyYWwubG9hZCwgeSA9IHByb3BfdG90YWwsIGNvbG91ciA9IGdlbnVzKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ2VudXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKHRhcmdldCB+IEJhY2tncm91bmQuc2FtcGxlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsKICBzY2FsZV95X2xvZzEwKGxpbWl0cz1jKDVlLTgsMSkpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIHRvdGFsIHJlYWRzIikgKwogIHhsYWIoIlZpcmFsIGxvYWQgKGdjL21sKSIpICsgCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJzb2xpZCIsICJkb3R0ZWQiKSkrIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApCgpgYGAKCiMjIyBEZWR1cCAtLSB2aXJhbCByZWFkcywgcHJvcCBhbGwgcmVhZHMsIGFuZCBwcm9wIHZpcmFsIHJlYWRzCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0xMn0KCmdnYXJyYW5nZSgKICBkZWR1cF9yZWFkcywKICBkZWR1cF9wcm9wX2FsbCwKICBkZWR1cF9wcm9wX3ZpcmFsLAogIG5yb3cgPSAzLAogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogIGFsaWduID0gImh2IgopCgpgYGAKCiMjIyAqKipGaW5hbCBwbG90KioqCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRSwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9OH0KCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy90YXJnZXRfb2ZmdGFyZ2V0X2RlZHVwLnBuZyIsd2lkdGg9OCxoZWlnaHQ9MTApCgojI2p1c3QgcGxvdCB2aXJhbCByZWFkcyBhbmQgcHJvcCB2aXJhbAoKZ2dhcnJhbmdlKAogIGRlZHVwX3JlYWRzLAogIGRlZHVwX3Byb3BfdmlyYWwsCiAgbnJvdyA9IDIsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgYWxpZ24gPSAiaHYiCikKCmdnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL3RhcmdldF9vZmZ0YXJnZXRfZGVkdXBfMjAyNS0wMS0wMS5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlc19wZGYvRmlndXJlXzNfMjAyNS0wMS0wMS5wZGYiLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQoKYGBgCgojIyMgLS0tLW5vZGVkdXAgcmVzdWx0cyAtLS0tCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9Nn0KIyNleHRyYXMgLSBubyBkZWR1cAoKbm9kZWR1cF9yZWFkcyA8LQogIG5vZGVkdXBfdmlyYWxfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk5lZ19jb250cm9sIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk1zcF9wNiIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKGNvdW50KSwKICAgIGNvbG91ciA9IGdlbnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ2VudXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKHRhcmdldCB+IEJhY2tncm91bmQuc2FtcGxlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgeWxhYigibG9nMTAoVmlyYWwgUmVhZHMpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKQoKbm9kZWR1cF9wcm9wX3ZpcmFsIDwtIAogIG5vZGVkdXBfdmlyYWxfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk5lZ19jb250cm9sIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk1zcF9wNiIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gVmlyYWwubG9hZCwgeSA9IHByb3BfdmlyYWwsIGNvbG91ciA9IGdlbnVzKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ2VudXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKHRhcmdldCB+IEJhY2tncm91bmQuc2FtcGxlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIHZpcmFsIHJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKQoKbm9kZWR1cF9wcm9wX2FsbCA8LSBub2RlZHVwX3ZpcmFsX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJOZWdfY29udHJvbCIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJNc3BfcDYiKSB8PgogIGdncGxvdChhZXMoeCA9IFZpcmFsLmxvYWQsIHkgPSBwcm9wX3RvdGFsLCBjb2xvdXIgPSBnZW51cykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCh0YXJnZXQgfiBCYWNrZ3JvdW5kLnNhbXBsZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV94X2xvZzEwKCkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgeWxhYigiUHJvcG9ydGlvbiBvZiB0b3RhbCByZWFkcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykKCmdnYXJyYW5nZSgKICBub2RlZHVwX3JlYWRzLAogIG5vZGVkdXBfcHJvcF9hbGwsCiAgbm9kZWR1cF9wcm9wX3ZpcmFsLAogIG5yb3cgPSAzLAogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogIGFsaWduID0gImh2IgopCgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvdGFyZ2V0X29mZnRhcmdldF9ub2RlZHVwLnBkZiIsd2lkdGg9OCxoZWlnaHQ9MTApCgpgYGAKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoK